package com.jic.order.impl;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.jic.common.base.vo.RestResult;
import com.jic.member.api.rest.MememberApi;
import com.jic.member.response.MememberUserResponse;
import com.jic.order.entity.OrderParent;
import com.jic.order.mapper.OrderParentMapper;
import com.jic.order.request.FrontPayOrderRequest;
import com.jic.order.service.OrderOperateService;
import com.jic.order.service.WXService;
import com.jic.order.utils.WxPayConfiguration;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author wj
 * @Description:
 * @date 2020-10-21 19:12
 */
@Service
@Slf4j
public class WXServiceImpl implements WXService {

    @Autowired
    private OrderParentMapper orderParentMapper;
    @Autowired
   private OrderOperateService orderOperateService;

    @Autowired
    private MememberApi mememberApi;

    @Value("${wx.pay.notifyUrl}")
    private String notifyUrl;

    /**
     * 统一下单
     *
     * @return
     * @throws Exception
     */
    @Override
    public Map unifiedOrder(FrontPayOrderRequest request) throws Exception {

        try {
            OrderParent orderParent = orderParentMapper.queryByPrimaryKey(request.getParentOrderNo());
            if (orderParent == null) {
                throw new Exception("订单不存在");
            }
            RestResult<MememberUserResponse> responseRestResult = mememberApi.queryMemberUserInfo(orderParent.getBuyerId());
            if (!RestResult.checkIsSuccess(responseRestResult)) {
                throw new Exception("支付失败,用户不存在");
            }
            //初始化数据
            WxPayConfiguration configUtil = new WxPayConfiguration();
            WXPay wxPay = new WXPay(configUtil);
            //封装微信第一签名
            Map<String, String> data = this.signMap(configUtil, orderParent, responseRestResult.getData());
            //生成签名
            String sign = WXPayUtil.generateSignature(data, configUtil.getKey(), WXPayConstants.SignType.MD5);
            data.put("sign", sign);
            String str = WXPayUtil.mapToXml(data);
            log.info("map转xml==================>>:{}" + str);
            //使用官方API请求预付订单
            Map<String, String> response = wxPay.unifiedOrder(data);
            Map<String, String> payMap = new HashMap<String, String>();
            String returnCode = response.get("return_code");    //获取返回码
            log.info("使用官方API请求预付订单==================>>>:{}" + response);
            //判断返回状态码是否成功
            if (returnCode.equals("SUCCESS")) {
                //成功后接受微信返回的参数
                payMap.put("appId", configUtil.getAppID());
                payMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
                payMap.put("nonceStr", WXPayUtil.generateNonceStr());
                payMap.put("signType", "MD5");
                payMap.put("package", "prepay_id=" + response.get("prepay_id"));
                String paySign = WXPayUtil.generateSignature(payMap, configUtil.getKey());
                payMap.put("paySign", paySign);
            } else {
                log.info("没有返回我接受到的微信参数");
            }
            return payMap;
        } catch (Exception e) {
            log.error("支付异常", e);
        }
        throw new Exception("下单失败");
    }


    /**
     * 回调
     *
     * @param notifyData
     * @return
     */
    @Override
    public String payBack(String notifyData) {
        log.info("======================微信支付异步结果逻辑处理开始=================================");
        WxPayConfiguration config = null;
        try {
            config = new WxPayConfiguration();
        } catch (Exception e) {
            log.error("config配置异常", e);
        }
        WXPay wxpay = new WXPay(config);
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            // 调用官方SDK转换成map类型数据
            notifyMap = WXPayUtil.xmlToMap(notifyData);
            log.info("返回的map----------------" + notifyMap);
            log.info("返回的错误代码--------" + notifyMap.get("err_code") + "返回的错误信息--------" + notifyMap.get("err_code_des"));
            //验证签名是否有效，有效则进一步处理
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                //状态
                String return_code = notifyMap.get("return_code");
                //商户订单号
                String out_trade_no = notifyMap.get("out_trade_no");
                String userId = notifyMap.get("attach");
                if (return_code.equals("SUCCESS")) {
                    if (out_trade_no != null) {
                        //业务数据持久化
                        //修改数据库支付状态
                        //修改数据库支付方式
                        System.err.println("-------------------------------支付成功----------------------");
                        log.info("微信手机支付回调成功订单号:{}", out_trade_no);
                        FrontPayOrderRequest request = new FrontPayOrderRequest();
                        request.setParentOrderNo(out_trade_no);
                        orderOperateService.pay(request);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        log.info("微信手机支付回调失败订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }
                }
                return xmlBack;
            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                //失败的数据要不要存储？
                log.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return xmlBack;
        }
    }

    /**
     * 第一次请求微信封装参数
     *
     * @param configUtil
     * @param orderParent
     * @return
     */
    private Map<String, String> signMap(WxPayConfiguration configUtil, OrderParent orderParent, MememberUserResponse mememberUserResponse) {
        //微信的支付单位是分所以要转换一些单位
        BigDecimal cardprice1 = orderParent.getBuyTotalAmount().multiply(new BigDecimal(100));
        String totalproce = String.valueOf(1);
        log.info(orderParent.getBuyTotalAmount() + "元=" + totalproce + "分");
        Map<String, String> data = new HashMap<>();
        //appid
        data.put("appid", configUtil.getAppID());
        //商户号
        data.put("mch_id", configUtil.getMchID());
        //随机字符串
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        String body = "测试微信支付";
        data.put("body", body);//商品描述
        data.put("out_trade_no", orderParent.getParentOrderNo()); //商品订单号
        data.put("total_fee", totalproce);  // 总金额
        data.put("spbill_create_ip", "192.168.0.1");//终端IP
        data.put("notify_url", notifyUrl);//回调地址
        data.put("trade_type", "JSAPI");//交易类型
        data.put("openid", mememberUserResponse.getUnionId());
        //附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
        data.put("attach", String.valueOf(orderParent.getBuyerId()));
        return data;
    }

}
